﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.ComponentModel;
using System.Diagnostics;
using FtpLib;
using CSharpTest.Net.Processes;


namespace BD2MKV
{

    public class ReportMessage
    {
        public int thread;
        public string line;
        public int type;
    }

    public class Muxer : ICloneable
    {
        public string destDir = null;
        public string sourceDir = null;
        public string label = null;
        public string tempDir = null;
        public int crf = 0;

        public int jobType = 0;
        public int dependsOn = 0;
        public int jobId = 0;
        public int jobStatus = 0;
        public BackgroundWorker worker = null;
        public int thread = 0;
        public bool dDTS = true;

        public string ftpServer = null;
        public string ftpUserName = null;
        public string ftpPWD = null;
        public string ftpDir = null;
      
        private List<string> tempFiles = new List<string>();

        public MXPlaylist muxPlaylist;

        public object Clone()
        {
            return this.MemberwiseClone();
        }


        public Muxer(string sDir, string dDir)
        {
            destDir = dDir;
            sourceDir = sDir;
            muxPlaylist = new MXPlaylist();
        }

        private void EncodeOnErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 1;
            if (e.Data == null)
                msg.line = "null";
            else
                msg.line = e.Data;

            int progress = 0;
            int index = 0;
            double num = 0;

            if (msg.line.StartsWith("["))
            {
                index = msg.line.LastIndexOf('[');
                num = Convert.ToDouble(msg.line.Substring(index + 1, msg.line.IndexOf('%') - index - 1));
                progress = (int)(num * (double)10);

                if (index != 0) 
                    msg.line = "###---###Indexing";
                else
                    msg.line = "###---###Encoding";

                
                worker.ReportProgress(progress, msg);
            }
            else
                worker.ReportProgress(0, msg);
        }

        private void EncodeOnOutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 1;
            if (e.Data == null)
                msg.line = "null";
            else
                msg.line = e.Data;

            
            if (msg.line.StartsWith("["))
            {
                
                int progress = Convert.ToInt32(msg.line.Substring(1,msg.line.IndexOf('.') - 1));
                msg.line = "###---###Encoding";
                worker.ReportProgress(progress, msg);
            } else
                worker.ReportProgress(0, msg);
        }

        private void SubsOnOutputDataReceived(object sender, ProcessOutputEventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 1;
            
            if (e.Data == null)
                msg.line = "null";
            else
                msg.line = e.Data;

            
            if (msg.line.StartsWith("Decoding frame"))
            {
                string []token = msg.line.Split(' ');
                string []frame = token[2].Split('/');
                int currentFrame = Convert.ToInt16(frame[0]);
                int lastFrame = Convert.ToInt16(frame[1]);
                msg.line = "###---###Decoding";
                int progress = (int)(((double)currentFrame / (double)lastFrame) * 1000); 
                worker.ReportProgress(progress, msg);
            }
            else
                worker.ReportProgress(0, msg);
            
        }

        private void DemuxOnOutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 1;
            
            if (e.Data == null)
                msg.line = "null";
            else
                msg.line = e.Data;

            if (msg.line.EndsWith("%"))
            {
                msg.line = msg.line.TrimEnd('%');
                int progType = 2;
                string status = msg.line.Substring(0, msg.line.IndexOf(":"));
                switch (status)
                {
                    case "analyze":
                        msg.line = msg.line.Replace("analyze: ", "");
                        progType = 1;
                        break;
                    case "process":
                        msg.line = msg.line.Replace("process: ", "");
                        progType = 2;
                        break;
                    case "Progress":
                        msg.line = msg.line.Replace("Progress: ", "");
                        progType = 3;
                        break;
                    default:
                        msg.line = msg.line.Replace(status + ":", "");
                        msg.line = msg.line.Trim();
                        progType = 4;
                        break;
                }

                int progress = Convert.ToInt16(msg.line) * 10;

                msg.line = "###---###";
                switch (progType)
                {
                    case 1:
                        msg.line += "Analyzing";
                        break;
                    case 2:
                    case 3:
                        msg.line += "Processing";
                        break;
                    case 4:
                        msg.line += status;
                        break;
                }
                worker.ReportProgress(progress, msg);
            }
            else
            {
                worker.ReportProgress(0, msg);
                if (msg.line.StartsWith("Video"))
                {
                    String[] token = msg.line.Split(' ');
                    muxPlaylist.frames = Convert.ToInt32(token[4]);                    
                }
                else if (msg.line.StartsWith("Subtitle"))
                {
                    String[] token = msg.line.Split(' ');
                    string track = token[2];
                    foreach (MXStreams m in muxPlaylist.muxStreams)
                    {
                        if (m.number == track)
                            m.captions = Convert.ToInt32(token[4]);
                    }
                }
            }
        }

        private void DemuxOnErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 2;
            if (e.Data == null)
                msg.line = "null";
            else
                msg.line = e.Data;
            worker.ReportProgress(0, msg);
        }


        private void DemuxOnProcessExited(object sender, EventArgs e)
        {
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 1;
            msg.line = "Finished.";
            worker.ReportProgress(100, msg);
        }

        public void DeMux()
        {
            string eac = "";

            if (!Directory.Exists(destDir)) Directory.CreateDirectory(destDir);

            string plist = muxPlaylist.name;
            plist = plist.Remove(plist.Length - 5);
                
            eac += "\"" + sourceDir + "\\PLAYLIST\\" + muxPlaylist.name + "\" ";
            
            
            
            foreach (MXStreams clipStream in muxPlaylist.muxStreams)
            {

                string fileName = tempDir + plist + "." + clipStream.number;
                eac += clipStream.number + ": \"" +fileName;

                switch (clipStream.codec)
                {
                    case "AVC":
                        eac += ".mkv\" -seekToIFrames ";
                        tempFiles.Add(fileName + ".mkv");
                        break;
                    case "VC-":
                        eac += ".mkv\" -seekToIFrames ";
                        tempFiles.Add(fileName + ".mkv"); 
                        break;
                    case "DTS":
                        eac += ".dts\" -core ";
                        tempFiles.Add(fileName + ".dts");
                        if (clipStream.DTSHD && dDTS)
                        {
                            eac += clipStream.number + ": \"" + fileName;
                            eac += ".flac\" ";
                            tempFiles.Add(fileName + ".flac");
                        }
                        break;
                    case "LPC":
                        eac += ".flac\" ";
                        tempFiles.Add(fileName + ".flac");
                        break;
                    case "AC3":
                    case "Tru":
                        eac += ".ac3\" ";
                        tempFiles.Add(fileName + ".ac3");
                        break;
                    case "PGS":
                        eac += ".sup\" ";
                        tempFiles.Add(fileName + ".sup");
                        break;
                    default:
                        break;
                }
            }

            eac += "1: \"" + tempDir + plist + ".chapters.txt\" -progressnumbers -log=\"" + tempDir + plist + ".log\"";
            tempFiles.Add(tempDir + plist + ".chapters.txt");
            tempFiles.Add(tempDir + plist + ".log");

            if (!BDMuxSettings.eac3toLocation.EndsWith("\\"))
                BDMuxSettings.eac3toLocation += "\\";

            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo.UseShellExecute = false;
            proc.EnableRaisingEvents = true;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.OutputDataReceived += new DataReceivedEventHandler(DemuxOnOutputDataReceived);
            proc.ErrorDataReceived += new DataReceivedEventHandler(DemuxOnErrorDataReceived);
            proc.Exited += new EventHandler(DemuxOnProcessExited);
            proc.StartInfo.FileName = "\"" + BDMuxSettings.eac3toLocation + "eac3to.exe\"";
            proc.StartInfo.Arguments = eac;
            
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 3;
            msg.line = " ****************************\n" +
                       "Starting  : " + proc.StartInfo.FileName + "\n" +
                       "Parameters: " + proc.StartInfo.Arguments + "\n" +
                       "*****************************";
            worker.ReportProgress(0, msg);

            proc.Start();
            proc.BeginOutputReadLine();
            proc.WaitForExit();                      
        }

        public void Encode()
        {
            string x264 = "";
            string plist = muxPlaylist.name;
            plist = plist.Remove(plist.Length - 5);
            muxPlaylist.encode = true;

            switch (crf)
            {             
                case 1:
                    //Ultra High Quality big file size
                    x264 += "--keyint 240 --min-keyint 24 ";
                    x264 += "--fps " + muxPlaylist.framesNumerator.ToString() + "/" + muxPlaylist.framesDenominator.ToString() + " ";
                    x264 += "--ref 3 --crf 17.0 ";
                    x264 += "--vbv-maxrate 25000 --trellis 0 ";
                    x264 += "--fullrange on  ";
                    x264 += "--level 4.1 --threads auto --thread-input ";
                    x264 += "--output ";
                    break;
                case 2:
                    //High Quality try to keep file size under control - A keeper but no special effects
                    //(i.e. Rome, Twilight)
                    x264 += "--keyint 240 --min-keyint 24 --bframes 3 --b-adapt 2 ";
                    x264 += "--fps " + muxPlaylist.framesNumerator.ToString() + "/" + muxPlaylist.framesDenominator.ToString() + " ";
                    x264 += "--ref 3 --crf 18.5 ";
                    x264 += "--trellis 0 ";
                    x264 += "--fullrange on  ";
                    x264 += "--level 4.1 --threads auto --thread-input ";
                    x264 += "--output ";
                    break;
                case 3:
                    //Balanced - Kind of want to keep it, movie goes slow (i.e. Obsessed, The Holiday)
                    x264 += "--keyint 240 --min-keyint 24 ";
                    x264 += "--fps " + muxPlaylist.framesNumerator.ToString() + "/" + muxPlaylist.framesDenominator.ToString() + " ";
                    x264 += "--ref 3 --crf 20.0 ";
                    x264 += "--trellis 0 ";
                    x264 += "--fullrange on  ";
                    x264 += "--level 4.1 --threads auto --thread-input ";
                    x264 += "--output ";
                    break;
                case 4:
                    // Don't really like it (i.e. Observe & Report)
                    x264 += "--keyint 240 --min-keyint 24 ";
                    x264 += "--fps " + muxPlaylist.framesNumerator.ToString() + "/" + muxPlaylist.framesDenominator.ToString() + " ";
                    x264 += "--ref 3 --crf 21.5 ";
                    x264 += "--trellis 0 ";
                    x264 += "--fullrange on  ";
                    x264 += "--level 4.1 --threads auto --thread-input ";
                    x264 += "--output ";
                    break;
                case 5:
                    //Standard - Anime 
                    x264 += "--keyint 240 --min-keyint 24 ";
                    x264 += "--fps " + muxPlaylist.framesNumerator.ToString() + "/" + muxPlaylist.framesDenominator.ToString() + " ";
                    x264 += "--ref 3 --crf 23.0 ";
                    x264 += "--trellis 0 ";
                    x264 += "--fullrange on  ";
                    x264 += "--level 4.1 --threads auto --thread-input ";
                    x264 += "--output ";
                    break;
            }
                
            foreach (MXStreams clipStream in muxPlaylist.muxStreams)
            {

                switch (clipStream.codec)
                {
                    case "AVC":
                    case "VC-":
                        string fileName = tempDir + plist + "." + clipStream.number;
                        string param = "";
                        if (clipStream.codec == "AVC")
                            param += x264 + "\"" + fileName + "-enc.mkv\" " + "\"" + fileName + ".mkv\"";
                        else
                            param += x264 + "\"" + fileName + "-enc.mkv\" " + "\"" + fileName + ".mkv\"";

                        if (!BDMuxSettings.x264Location.EndsWith("\\"))
                            BDMuxSettings.x264Location += "\\";

                        System.Diagnostics.Process procX264 = new System.Diagnostics.Process();
                        procX264.StartInfo.UseShellExecute = false;
                        procX264.EnableRaisingEvents = true;
                        procX264.StartInfo.CreateNoWindow = true;
                        procX264.StartInfo.RedirectStandardOutput = true;
                        procX264.StartInfo.RedirectStandardError = true;
                        procX264.StartInfo.RedirectStandardInput = true;
                        procX264.StartInfo.ErrorDialog = false;

                        procX264.OutputDataReceived += new DataReceivedEventHandler(EncodeOnOutputDataReceived);
                        procX264.ErrorDataReceived += new DataReceivedEventHandler(EncodeOnErrorDataReceived);
                        procX264.Exited += new EventHandler(DemuxOnProcessExited);
                        procX264.StartInfo.FileName = "\"" + BDMuxSettings.x264Location + "x264.exe\"";
                        procX264.StartInfo.Arguments = param;

                        ReportMessage msg = new ReportMessage();
                        msg.thread = thread;
                        msg.type = 3;
                        msg.line = " ****************************\n" +
                                   "Starting  : " + procX264.StartInfo.FileName + "\n" +
                                   "Parameters: " + procX264.StartInfo.Arguments + "\n" +
                                   "*****************************";
                        worker.ReportProgress(0, msg);

                        procX264.Start();
                        procX264.StandardInput.Close();
                        procX264.BeginOutputReadLine();
                        procX264.BeginErrorReadLine();                        
                        procX264.WaitForExit();                        

                        tempFiles.Add(fileName + "-enc.mkv");
                        break;
                }
            }
        }

        public void Subtitles()
        {
            //Convert Subtitles
            string plist = muxPlaylist.name;
            plist = plist.Remove(plist.Length - 5);
            foreach (MXStreams track in muxPlaylist.muxStreams)
            {
                if (track.codec == "PGS")
                {
                    string supFile = tempDir + plist + "." + track.number;
                    tempFiles.Add(supFile + ".sub");
                    tempFiles.Add(supFile + ".idx");
                    
                    if (!BDMuxSettings.BDSup2SubLocation.EndsWith("\\"))
                        BDMuxSettings.BDSup2SubLocation += "\\";



                    ProcessRunner run = new ProcessRunner("java", "-jar \"" + BDMuxSettings.BDSup2SubLocation + "BDSup2Sub.jar\" \"" + supFile + ".sup\" \"" + supFile + ".idx\" /res:keep /lang:" + LanguageCodes.GetTwoLetterLang(track.language));
                    run.OutputReceived += new ProcessOutputEventHandler(SubsOnOutputDataReceived);
                    ReportMessage msg = new ReportMessage();
                    msg.thread = thread;
                    msg.type = 3;
                    msg.line = " ****************************\n" +
                               "Starting  : " + "java"  + "\n" +
                               "Parameters: " + "-jar \"" + BDMuxSettings.BDSup2SubLocation + "BDSup2Sub.jar\" \"" + supFile + ".sup\" \"" + supFile + ".idx\" /res:keep /lang:" + LanguageCodes.GetTwoLetterLang(track.language) + "\n" +
                               "*****************************";
                    worker.ReportProgress(0, msg);
                    run.Run();
                    
                    //System.Diagnostics.Process procSubs = new System.Diagnostics.Process();
                    //procSubs.StartInfo.UseShellExecute = false;
                    //procSubs.EnableRaisingEvents = true;
                    //procSubs.StartInfo.CreateNoWindow = true;
                    //procSubs.StartInfo.RedirectStandardOutput = true;
                    //procSubs.StartInfo.RedirectStandardError = true;
                    //procSubs.OutputDataReceived += new DataReceivedEventHandler(SubsOnOutputDataReceived);
                    //procSubs.ErrorDataReceived += new DataReceivedEventHandler(DemuxOnErrorDataReceived);                   
                    //procSubs.Exited += new EventHandler(DemuxOnProcessExited);
                    //procSubs.StartInfo.FileName = "java";
                    //procSubs.StartInfo.Arguments = "-jar \"" + BDMuxSettings.BDSup2SubLocation + "BDSup2Sub.jar\" \"" + supFile + ".sup\" \"" + supFile + ".idx\" /res:keep /lang:" + LanguageCodes.GetTwoLetterLang(track.language);
                    
                    //ReportMessage msg = new ReportMessage();
                    //msg.thread = thread;
                    //msg.type = 3;
                    //msg.line = " ****************************\n" +
                    //           "Starting  : " + procSubs.StartInfo.FileName + "\n" +
                    //           "Parameters: " + procSubs.StartInfo.Arguments + "\n" +
                    //           "*****************************";
                    //worker.ReportProgress(0, msg);

                    //procSubs.Start();
                    //procSubs.BeginOutputReadLine();
                    //procSubs.WaitForExit();
                }
            }
        }

        public void Mux()
        {
            //Muxing
            

            string plist = muxPlaylist.name;
            plist = plist.Remove(plist.Length - 5);
            string mkvargs = "-o \"" + destDir + muxPlaylist.finalName + "\" ";
            string torder = "";
            int counter = 0;
            foreach (MXStreams track in muxPlaylist.muxStreams)
            {
                string supFile = tempDir + plist + "." + track.number;
                string streamno = "0";
                
                
                switch (track.codec)
                {
                    case "AVC":
                    case "VC-":
                        mkvargs += "--default-track 1:no --forced-track 1:no --display-dimensions 1:1920x1080 -d 1 -A -S -T --no-global-tags --no-chapters ";
                        
                        if (muxPlaylist.encode)
                            mkvargs += "\"" + supFile + "-enc.mkv\" ";
                        else
                            if (track.codec == "AVC")
                                mkvargs += "\"" + supFile + ".mkv\" ";
                            else
                                mkvargs += "\"" + supFile + ".mkv\" ";
                            
                        streamno = "1";
                        break;
                    case "DTS":
                        mkvargs += "--language 0:" + track.language + " --forced-track 0:no -a 0 -D -S -T --no-global-tags --no-chapters ";
                        mkvargs += "\"" + supFile + ".dts\" ";
                        torder += string.Format("{0}", counter) + ":" + streamno + ",";
                        if (track.DTSHD && dDTS)
                        {
                            counter++;
                            mkvargs += "--language 0:" + track.language + " --forced-track 0:no -a 0 -D -S -T --no-global-tags --no-chapters ";
                            mkvargs += "\"" + supFile + ".flac\" ";
                        }
                        break;
                    case "AC3":
                        mkvargs += "--language 0:" + track.language + " --forced-track 0:no -a 0 -D -S -T --no-global-tags --no-chapters ";
                        mkvargs += "\"" + supFile + ".ac3\" ";
                        break;
                    case "PGS":
                        mkvargs += "--language 0:" + track.language + " --forced-track 0:no -s 0 -D -A -T --no-global-tags --no-chapters ";
                        mkvargs += "\"" + supFile + ".idx\" ";
                        break;
                    default:
                        break;
                }
                torder += string.Format("{0}", counter) + ":" + streamno + ",";
                counter++;
            }
            torder = torder.TrimEnd(',');
            mkvargs += "--track-order " + torder + " --chapters \"" + tempDir + plist + ".chapters.txt\"";
            if (!BDMuxSettings.mkvmergeLocation.EndsWith("\\"))
                BDMuxSettings.mkvmergeLocation += "\\";

            System.Diagnostics.Process procMux = new System.Diagnostics.Process();
            procMux.StartInfo.UseShellExecute = false;
            procMux.EnableRaisingEvents = true;                        
            procMux.StartInfo.CreateNoWindow = true;
            procMux.StartInfo.RedirectStandardOutput = true;
            procMux.StartInfo.RedirectStandardError = true;
            procMux.OutputDataReceived += new DataReceivedEventHandler(DemuxOnOutputDataReceived);
            procMux.ErrorDataReceived += new DataReceivedEventHandler(DemuxOnErrorDataReceived);
            procMux.Exited += new EventHandler(DemuxOnProcessExited);
            procMux.StartInfo.FileName = "\"" + BDMuxSettings.mkvmergeLocation + "mkvmerge.exe\"";
            procMux.StartInfo.Arguments = mkvargs;
            
            ReportMessage msg = new ReportMessage();
            msg.thread = thread;
            msg.type = 3;
            msg.line = " ****************************\n" +
                       "Starting  : " + procMux.StartInfo.FileName + "\n" +
                       "Parameters: " + procMux.StartInfo.Arguments + "\n" +
                       "*****************************";
            worker.ReportProgress(0, msg);

            procMux.Start();
            procMux.BeginOutputReadLine();
            procMux.WaitForExit();
        }

        public void RemoveTemps()
        {

            int numberOfFiles = tempFiles.Count;
            int finishedFiles = 0;
            ReportMessage msg = new ReportMessage();

            foreach (string file in tempFiles)
            {
                FileInfo delfile = new FileInfo(@file);
                try
                {
                    msg.line = delfile.FullName + " deleted...";
                    delfile.Delete();
                    finishedFiles++;
                    double progress = ((double)finishedFiles / numberOfFiles);
                    int progressValue = (int)Math.Round(progress * 1000);
                    if (progressValue < 0) progressValue = 0;
                    if (progressValue > 1000) progressValue = 1000;
                    msg.thread = thread;
                    msg.type = 1;
                    worker.ReportProgress(progressValue, msg);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            try
            {
                Directory.Delete(tempDir);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }        
        }

        public void FTP()
        {
            if (!ftpDir.EndsWith("/"))
                ftpDir += "/";

            //if (ftpDir.StartsWith("/"))
            //{
            //    ftpDir = ftpDir.TrimEnd('/');
            //    ftpDir = "/%2F" + ftpDir;
            //}
            //else
            //    ftpDir = "/" + ftpDir;

            //string uriMk = "ftp://" + ftpServer + ftpDir;
            string uriMk = ftpDir;
            //FtpWebRequest reqMkFTP;
            FTPFactory FTP = new FTPFactory();
            string tmpDir = ftpDir;

            bool created = false;
            
            FTP.remoteHost = ftpServer;
            FTP.remoteUser = ftpUserName;
            FTP.remotePass = ftpPWD;
            FTP.login();

            while (!created)
            {
                //reqMkFTP = (FtpWebRequest)FtpWebRequest.Create
                //    (new Uri(uriMk));
               //reqMkFTP.Credentials = new NetworkCredential(ftpUserName, ftpPWD);
                

                //reqMkFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
                try
                {
                    FTP.mkdir(uriMk);
                    //WebResponse ftpResp = reqMkFTP.GetResponse();
                    if (tmpDir == ftpDir)
                    {
                        created = true;
                        break;
                    }
                    else
                        tmpDir = ftpDir + "dummy/";
                }
                //catch (WebException webEx)
                catch (IOException webEx)
                {
                    //if (((FtpWebResponse)(webEx.Response)).StatusCode != FtpStatusCode.ActionNotTakenFileUnavailable)
                    //{
                        MessageBox.Show(webEx.Message, "Create Directory Error");
                    //    break;
                    //}
                    //if (((FtpWebResponse)(webEx.Response)).StatusDescription.StartsWith("550 Directory already exists"))
                    //{
                    //    created = true;
                    //    break;
                    //}
                }
                tmpDir = tmpDir.TrimEnd('/');
                if (tmpDir == "")
                {
                    MessageBox.Show("Can't create directory", "Create Directory Error");
                    break;
                }
                tmpDir = tmpDir.Remove(tmpDir.LastIndexOf('/') + 1);
                //uriMk = "ftp://" + ftpServer + tmpDir;
                uriMk = tmpDir;

            }

            if (!created) return;

            FileInfo fileInf = new FileInfo(destDir + muxPlaylist.finalName);

            //string uri = "ftp://" + ftpServer + ftpDir + fileInf.Name;
            string uri = fileInf.Name;
            //FtpWebRequest reqFTP;

            //reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));

            //reqFTP.Credentials = new NetworkCredential(ftpUserName, ftpPWD);
            //reqFTP.KeepAlive = false;
            //reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
            //reqFTP.UseBinary = true;
            //reqFTP.ContentLength = fileInf.Length;

            //int buffLength = 2048;
            //byte[] buff = new byte[buffLength];
            //int contentLen;

            //FileStream fs = fileInf.OpenRead();

            try
            {
                FTP.upload(uri);
                //Stream strm = reqFTP.GetRequestStream();

                //contentLen = fs.Read(buff, 0, buffLength);

                

                //long finishedBytes = 0;
                
                //int j = 0;
                //ReportMessage msg = new ReportMessage();

                //while (contentLen != 0)
                //{
                //    strm.Write(buff, 0, contentLen);

                //    finishedBytes += contentLen;
                //    j++;
                //    if (j == 50)
                //    {
                //        double progress = ((double)finishedBytes / fileInf.Length);
                //        int progressValue = (int)Math.Round(progress * 100);
                //        if (progressValue < 0) progressValue = 0;
                //        if (progressValue > 100) progressValue = 100;
                //        msg.thread = thread;
                //        msg.line = finishedBytes.ToString() + " completed...";
                //        msg.type = 1;
                //        worker.ReportProgress(progressValue, msg);

                //        j = 0;
                //    }
                //    contentLen = fs.Read(buff, 0, buffLength);
                //}

                //strm.Close();
                //fs.Close();
            }
            //catch (WebException ex)
            catch (IOException ex)
            {
                //if (((FtpWebResponse)(ex.Response)).StatusCode != FtpStatusCode.ActionNotTakenFileUnavailable)
                    MessageBox.Show(ex.Message, "Upload Error");

                //if (((FtpWebResponse)(ex.Response)).StatusDescription.StartsWith("550 Permission denied"))
                //    MessageBox.Show("The file already exists, or access is denied", "Upload Error");
            }

        }
    }
}
